using System;
using BitBenderGames;
using OWL.Rendering.HRP;
using UnityEngine;
using WorldMap;
using Yoozoo.Core.Common;
using Yoozoo.Gameplay.City;
using Yoozoo.HRP.Runtime;
using Yoozoo.Mars.Got;

namespace Yoozoo.Modules.InnerCity.TouchCamera
{
    [Serializable]
    public struct QualityLod
    {
        public float Lod1;
        public float Lod2;
        public float Lod3;
        public float Lod4;
        public float Lod5;
        public bool needHideShadow;
    }
    public class InnerCityCameraComponent : CameraComponent
    {
        public float ZoomMaxLOD1;
        public float ZoomMaxLOD2;
        public float ZoomMaxLOD3;
        public float ZoomMaxLOD4;
        public float ZoomMaxLOD5;
        
        public QualityLod LowQualityLod;
        public QualityLod MediumQualityLod;
        public QualityLod HighQualityLod;
        public QualityLod VeryHighQualityLod;
        public QualityLod PerfectQualityLod;

        private Vector3 _lastPosition;
        private Quaternion _lastRotaition;

        private Camera mainCamera;
        public Vector3[] m_CornersPosition = new Vector3[4];

        public QualityLod CurrentLod;
        
        public static event Action<Vector2> luaMoveEventHandler;
        public  Vector2 CenterViewPosition { get; private set; }
        
        public static void AddLuaMoveEventHandler(Action<Vector2> action)
        {
            luaMoveEventHandler += action;
        }
        public static void RemoveLuaMoveEventHandler(Action<Vector2> action)
        {
            luaMoveEventHandler -= action;
        }

        void Start()
        {
            if (QualityManager.Inst)
            {
                OnQualityChanged(QualityManager.Inst.CurrentQuality);
            }
            mainCamera = GetComponent<Camera>();
            DeviceQuality.Instance.RegisterAction(OnQualityChanged);
		}

        void OnDestroy()
        {
            DeviceQuality.Instance.UnRegisterAction(OnQualityChanged);
            //销毁时 清空静态监听,防止编辑器模式下 MainCressnUI.OnClose未触发导致的静态监听残留
            luaMoveEventHandler = null;
        }
        
        void Update()
        {
            Vector3 curPosition = transform.position;
            Quaternion curRotation = transform.rotation;
            if (_lastPosition != curPosition || _lastRotaition != curRotation)
            {
                _lastPosition = curPosition;
                _lastRotaition = curRotation;
                FindGroundViewCorner();
                // 摄像机y轴会选择45度 所以现在中心点是等腰梯形中心点
                Vector3 point0 = (m_CornersPosition[0] + m_CornersPosition[1]) * 0.5f;
                Vector3 point1 = (m_CornersPosition[2] + m_CornersPosition[3]) * 0.5f;
                Vector3 targetPosition = (point0 + point1) * 0.5f;
                targetPosition.y = 0;
        
#if UNITY_EDITOR
                Debug.DrawLine(mainCamera.transform.position, targetPosition, Color.yellow, 0, false);
#endif
        
                var currentPosition = new Vector2(targetPosition.x, targetPosition.z);
                UpdateCenterViewPosition(currentPosition);
            }
        }
        public void UpdateCenterViewPosition(Vector2 currentPosition)
        {
            bool isCameraMoving = false;
            if (currentPosition != CenterViewPosition)
            {
                //Debug.LogError( "更新视野位置：" + currentPosition.ToString());
                luaMoveEventHandler?.Invoke(currentPosition);
            }
            
            CenterViewPosition = currentPosition;

        }

        private void OnQualityChanged(QualityEnum quality)
        {
            float zoomDistanceMax = ZoomMaxLOD1;
            CurrentLod = LowQualityLod;
            switch (quality)
            {
                case QualityEnum.Low:
                    {
                        zoomDistanceMax = ZoomMaxLOD1;
                        CurrentLod = LowQualityLod;
                    }
                    break;
                case QualityEnum.Medium:
                    {
                        zoomDistanceMax = ZoomMaxLOD2;
                        CurrentLod = MediumQualityLod;
                    }
                    break;
                case QualityEnum.High:
                    {
                        zoomDistanceMax = ZoomMaxLOD3;
                        CurrentLod = HighQualityLod;
                    }
                    break;
                case QualityEnum.VeryHigh:
                    {
                        zoomDistanceMax = ZoomMaxLOD4;
                        CurrentLod = VeryHighQualityLod;
                    }
                    break;
                case QualityEnum.Perfect:
                    {
                        zoomDistanceMax = ZoomMaxLOD5;
                        CurrentLod = PerfectQualityLod;
                    }
                    break;
            }

            if (cameraController)
            {
                cameraController.UpdateZoomDistance(cameraController.ZoomDistanceMin, zoomDistanceMax,true);
                cameraController.UpdateCurrentLodParam(CurrentLod);
            }

        }

        public void UpdateCameraController()
        {
            if (QualityManager.Inst)
            {
                OnQualityChanged(QualityManager.Inst.CurrentQuality);
            }
        }
        
        private void FindGroundViewCorner()
        {
            
            Vector3[] planeConrners = GetCorners(mainCamera.nearClipPlane);

            Vector3 pos = mainCamera.transform.position;
            m_CornersPosition[0] = WorldMapUtility.GetIntersectionWithLineAndPlane(pos, pos - planeConrners[0],
                Vector3.up, Vector3.zero);
            m_CornersPosition[1] = WorldMapUtility.GetIntersectionWithLineAndPlane(pos, pos - planeConrners[1],
                Vector3.up, Vector3.zero);
            m_CornersPosition[2] = WorldMapUtility.GetIntersectionWithLineAndPlane(pos, pos - planeConrners[2],
                Vector3.up, Vector3.zero);
            m_CornersPosition[3] = WorldMapUtility.GetIntersectionWithLineAndPlane(pos, pos - planeConrners[3],
                Vector3.up, Vector3.zero);
        
        }
        private Vector3[] corners = new Vector3[4];
        private Vector3[] GetCorners(float distance)
        {
            //Vector3[] corners = new Vector3[4];

            float halfFOV = (mainCamera.fieldOfView * 0.5f) * Mathf.Deg2Rad;
            float aspect = mainCamera.aspect;

            float height = distance * Mathf.Tan(halfFOV);
            float width = height * aspect;

            // UpperLeft
            corners[0] = mainCamera.transform.position - (mainCamera.transform.right * width);
            corners[0] += mainCamera.transform.up * height;
            corners[0] += mainCamera.transform.forward * distance;

            // UpperRight
            corners[1] = mainCamera.transform.position + (mainCamera.transform.right * width);
            corners[1] += mainCamera.transform.up * height;
            corners[1] += mainCamera.transform.forward * distance;

            // LowerLeft
            corners[2] = mainCamera.transform.position - (mainCamera.transform.right * width);
            corners[2] -= mainCamera.transform.up * height;
            corners[2] += mainCamera.transform.forward * distance;

            // LowerRight
            corners[3] = mainCamera.transform.position + (mainCamera.transform.right * width);
            corners[3] -= mainCamera.transform.up * height;
            corners[3] += mainCamera.transform.forward * distance;

            return corners;
        }
    }
}